package ru.alt22.visor.php.ui.pages;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.window.Window;
import org.eclipse.php.internal.core.phpModel.phpElementData.PHPClassData;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkbenchPropertyPage;
import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
import org.eclipse.ui.dialogs.ISelectionStatusValidator;
import org.eclipse.ui.dialogs.PropertyPage;
import org.eclipse.ui.model.WorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchLabelProvider;

import ru.alt22.visor.php.properties.Properties;
import ru.alt22.visor.php.ui.PDToolsUIPlugin;
import ru.alt22.visor.php.ui.swt.OpenPhpClassDialog;
import ru.alt22.visor.php.ui.utils.LayoutUtils;

public class PHPTestsPropertyPage extends PropertyPage implements IWorkbenchPropertyPage {

	private Text phpExe;
	private Text script;
	private Text baseClass;

	protected Control createContents(Composite parent) {
		parent.setLayout(new GridLayout(3, false));
		GridData data = new GridData(GridData.FILL);
		data.grabExcessHorizontalSpace = true;
		parent.setLayoutData(data);

		createPHPExeControls(parent);
		creatAutoSelectProperties(parent);
		createManualSelectProperties(parent);

		useAutoSelect(false);

		readValues();

		return parent;
	}

	private void createPHPExeControls(Composite parent) {
		Label label = new Label(parent, SWT.NONE);
		label.setText("PHP Executable");

		phpExe = new Text(parent, SWT.BORDER);
		phpExe.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false));

		Button button = new Button(parent, SWT.NONE);
		button.setText("Browse");
		button.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				browseForPHPExe();
			}
		});
	}

	private void creatAutoSelectProperties(Composite parent) {
		LayoutUtils.addWrapper(parent, 3);

		Button checkBox = new Button(parent, SWT.CHECK);
		checkBox.setText("Create for popular TestCase framewerks");
		checkBox.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false, 3, 1));
		checkBox.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				useAutoSelect(((Button) e.getSource()).getSelection());
			}
		});

		checkBox.setEnabled(false);
	}

	protected void useAutoSelect(boolean selected) {
	}

	private void createManualSelectProperties(Composite parent) {
		LayoutUtils.addWrapper(parent, 3);

		Label label = new Label(parent, SWT.NONE);
		label.setText("PHP Tester script");

		script = new Text(parent, SWT.BORDER);
		script.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false));

		Button button = new Button(parent, SWT.NONE);
		button.setText("Browse");
		button.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				browseForScript();
			}
		});
		label = new Label(parent, SWT.NONE);
		label.setText("Base Test Cases class");

		baseClass = new Text(parent, SWT.BORDER);
		baseClass.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false));

		button = new Button(parent, SWT.NONE);
		button.setText("Browse");
		button.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				browseForBaseTestClass();
			}
		});
	}

	private void readValues() {
		if (null != Properties.getPHPExecutable(getProject())) {
			phpExe.setText(Properties.getPHPExecutable(getProject()));
		}
		if (null != Properties.getPHPExecutable(getProject())) {
			script.setText(Properties.getTestScript(getProject()));
		}
		if (null != Properties.getBaseTestClass(getProject())) {
			baseClass.setText(Properties.getBaseTestClass(getProject()));
		}
	}

	protected void browseForPHPExe() {
		FileDialog dialog = new FileDialog(getShell(), SWT.OPEN);

		Path file = getPhpExe();
		if (file != null) {
			dialog.setFileName(file.toString());
		}

		String[] extensions = new String[1];
		extensions[0] = "php.exe";
		dialog.setFilterExtensions(extensions);

		String[] names = new String[1];
		names[0] = "PHP Executable";
		dialog.setFilterNames(names);

		String path = dialog.open();
		if (null != path) {
			phpExe.setText(path);
		}
	}

	protected void browseForScript() {
		ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(getShell(), new WorkbenchLabelProvider(), new WorkbenchContentProvider());
		dialog.setInput(getProject().getWorkspace());
		IFile file = getScript();
		if (file != null) {
			dialog.setInitialSelection(file);
		}
		dialog.addFilter(new ViewerFilter() {
			public boolean select(Viewer viewer, Object parentElement, Object element) {
				if (element instanceof IProject) {
					return ((IProject) element).equals(PHPTestsPropertyPage.this.getProject());
				}
				return true;
			}
		});
		dialog.setAllowMultiple(false);
		dialog.setValidator(new ISelectionStatusValidator() {
			public IStatus validate(Object[] selection) {
				if (selection != null && selection.length > 0 && selection[0] instanceof IFile) {
					return new Status(IStatus.OK, PDToolsUIPlugin.PLUGIN_ID, IStatus.OK, "", null); //$NON-NLS-1$
				}
				return new Status(IStatus.ERROR, PDToolsUIPlugin.PLUGIN_ID, IStatus.ERROR, "", null); //$NON-NLS-1$
			}
		});

		if (dialog.open() == Window.OK) {
			file = (IFile) dialog.getFirstResult();
			String value = file.getProjectRelativePath().toString();
			script.setText(value);
		}
	}

	protected void browseForBaseTestClass() {
		OpenPhpClassDialog dialog = new OpenPhpClassDialog(getShell(), true);
		dialog.setProject(getProject());
		dialog.setFilterText(baseClass.getText());
		if (dialog.open() == Window.OK) {
			PHPClassData parentClass = dialog.getSelectedClass();
			if (parentClass != null) {
				baseClass.setText(parentClass.getName());
			}
		}
	}

	public boolean performOk() {
		Properties.setPHPExecutable(getProject(), phpExe.getText());
		Properties.setTestScript(getProject(), script.getText());
		Properties.setBaseTestClass(getProject(), baseClass.getText());
		return true;
	}

	private IProject getProject() {
		return (IProject) getElement();
	}

	private Path getPhpExe() {
		String value = phpExe.getText();
		if (value.length() == 0) {
			return null;
		}
		return new Path(value);
	}

	private IFile getScript() {
		String value = script.getText();
		if (value.length() == 0) {
			return null;
		}
		IPath path = getProject().getFullPath().append(value);
		return getProject().getWorkspace().getRoot().getFile(path);
	}

}